#[macro_use]
extern crate rbatis;

mod dbs;
mod features;
mod gql;
mod updater;
mod util;

use actix_cors::Cors;
use actix_web::{get, guard, http, web, App, HttpRequest, HttpResponse, HttpServer, Responder};
// use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};

use crate::gql::schema::{build_schema, graphiql, graphql};
//use crate::util::constant::CFG;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
  common::init::init(".", ".",".",".");
  db_diesel::migrate("./data/sqlite/ebstore");

  let schema: gql::schema::ActixSchema =
    build_schema(&common::init::DATABASE_URL.read().unwrap()).await;
  let port: u16 = 8180;
  println!("GraphQL UI: https://localhost:{}/v1", port);
/*
  // load ssl keys
  let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
  builder
    .set_private_key_file("key.pem", SslFiletype::PEM)
    .unwrap();
  builder.set_certificate_chain_file("cert.pem").unwrap();

   HttpServer::new(|| App::new().service(index))
  .bind_openssl("localhost:8080", builder)?
  .run()
  .await*/

  HttpServer::new(move || {
    let cors = Cors::default()
      .allow_any_origin()
      //.allowed_origin("https://www.rust-lang.org/")
      //.allowed_origin_fn(|origin, _req_head| {
      //    origin.as_bytes().ends_with(b".rust-lang.org")
      //})
      .allowed_methods(vec!["GET", "POST"])
      .allowed_headers(vec![http::header::AUTHORIZATION, http::header::ACCEPT])
      .allowed_header(http::header::CONTENT_TYPE)
      .max_age(3600);

    App::new()
      .wrap(cors)
      .data(schema.clone())
      .service(
        web::resource("v1" /*CFG.get("GQL_VER").unwrap()*/)
          .guard(guard::Post())
          .to(graphql),
      )
      .service(
        web::resource("v1i" /*CFG.get("GIQL_VER").unwrap()*/)
          .guard(guard::Get())
          .to(graphiql),
      )
      .service(
        web::resource("/update/{target}/{current_version}")
          .guard(guard::Get())
          .to(updater::update),
      )
  })
  .bind(format!("{}:{}", "localhost", port))?
  // .bind_openssl(&format!("localhost:{}", port), builder)?
  .run()
  .await
}
